use std::ffi::CString;
use std::os::raw::c_char;

use crate::config::app_config::CONFIG;
use crate::config::log_config::config_tracing_log;
use crate::tcp_server;

pub static mut CALLBACK: Option<extern "C" fn(*const c_char)> = None;

#[repr(C)]
pub struct MyApp;

impl MyApp {
    pub fn start_server() {
        let runtime = tokio::runtime::Builder::new_multi_thread()
            .enable_all()
            .build()
            .expect("build thread error");
        let _workd_guard = config_tracing_log().unwrap();
        let server_config = &CONFIG.server;
        let tcp_addr = &server_config.tcp;
        let http_addr = &server_config.http;

        /*runtime.spawn(async {
            http_server(http_addr)
                .await
                .expect("start http server error");
        });*/

        runtime.block_on(async {
            tcp_server(tcp_addr).await.expect("start tcp server error");
        })
    }

    pub fn rust_send_message_to_csharp(message: &str) {
        if let Ok(c_message) = CString::new(message) {
            send_msg_to_csharp(c_message.as_ptr());
        }
    }
}

/**
 *
 * 启动tcp server
 */
#[no_mangle]
pub extern "C" fn startServer() {
    println!("注册startServer");
    MyApp::start_server();
}

/**
 * 初始化 callback
 */
#[no_mangle]
pub extern "C" fn init_callback(callback: extern "C" fn(*const c_char)) {
    println!("注册init_callback");
    unsafe {
        CALLBACK = Some(callback);
    }
}

#[no_mangle]
pub extern "C" fn send_msg_to_csharp(msg: *const c_char) {
    unsafe {
        if let Some(callback) = CALLBACK {
            callback(msg);
        }
    }
}
